﻿// ===============================================================================
//  Copyright © NewSQL.CN. All rights reserved .
//  技术论坛：http://newsql.cn/
//  个人博客：http://www.ymind.net/
//  版权所有：NewSQL中文社区 彦铭工作室
// ===============================================================================

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Runtime.InteropServices;
using Newsql.Data.RDBMS.Results;

namespace Newsql.Data.RDBMS
{
	/// <summary>
	/// 表示基本的查询构造器。
	/// </summary>
	/// <typeparam name="T">指定查询结果的对象的类型。</typeparam>
	[ComVisible(true)]
	public class QueryBuilder<T> where T : BaseQuery
	{
		/// <summary>
		/// 查询构造器使用的查询对象。
		/// </summary>
		protected internal readonly T Query;

		/// <summary>
		/// 初始化 <see cref="QueryBuilder&lt;T&gt;"/> 的新实例。
		/// </summary>
		/// <param name="obj">指定查询结果的类型。</param>
		public QueryBuilder(T obj) { this.Query = obj; }

		/// <summary>
		/// 映射记录集到 <see cref="QueryBuilder&lt;T&gt;"/> 的实例。
		/// </summary>
		/// <param name="objectRecordMapper">指定一个参数为 <see cref="System.Data.Common.DbDataReader"/> 且返回值为 <see cref="System.Object"/> 的 Func 委托。</param>
		/// <returns>返回 <see cref="QueryBuilder&lt;T&gt;"/> 的实例。</returns>
		public QueryBuilder<T> Map(Func<DbDataReader, object> objectRecordMapper)
		{
			this.Query.Map(objectRecordMapper);

			return this;
		}

		/// <summary>
		/// 为查询添加一个 <see cref="System.Data.Common.DbParameter"/>。
		/// </summary>
		/// <param name="parameterName"><see cref="System.Data.Common.DbParameter"/> 的名称。默认值为空字符串 ("")。</param>
		/// <param name="value">一个 <see cref="System.Object"/>，它是该参数的值。默认值为 null。</param>
		/// <param name="parameterType"><see cref="System.Data.DbType"/> 值之一。默认值为 <see cref="System.Data.DbType.String"/>。</param>
		/// <param name="paramSize">列中数据的最大大小（以字节为单位）。默认值是从参数值推导出的。</param>
		/// <returns>返回 <see cref="QueryBuilder&lt;T&gt;"/> 的实例。</returns>
		public QueryBuilder<T> AddParameter(string parameterName, object value, DbType parameterType, int paramSize)
		{
			this.Query.AddParameter(parameterName, value, parameterType, paramSize);

			return this;
		}

		/// <summary>
		/// 为查询添加一个 <see cref="System.Data.Common.DbParameter"/>。
		/// </summary>
		/// <param name="parameterName"><see cref="System.Data.Common.DbParameter"/> 的名称。默认值为空字符串 ("")。</param>
		/// <param name="parameterValue">一个 <see cref="System.Object"/>，它是该参数的值。默认值为 null。</param>
		/// <param name="parameterType"><see cref="System.Data.DbType"/> 值之一。默认值为 <see cref="System.Data.DbType.String"/>。</param>
		/// <returns>返回 <see cref="QueryBuilder&lt;T&gt;"/> 的实例。</returns>
		public QueryBuilder<T> AddParameter(string parameterName, object parameterValue, DbType parameterType)
		{
			this.Query.AddParameter(parameterName, parameterValue, parameterType);

			return this;
		}

		/// <summary>
		/// 设置在终止执行命令的尝试并生成错误之前的等待时间。
		/// </summary>
		/// <param name="timeout">等待命令执行的时间（以秒为单位）。</param>
		/// <returns>返回 <see cref="QueryBuilder&lt;T&gt;"/> 的实例。</returns>
		public QueryBuilder<T> CommandTimeout(int timeout)
		{
			this.Query.CommandTimeout = timeout;

			return this;
		}

		/// <summary>
		/// 使用事务处理。
		/// </summary>
		/// <param name="transaction">指定 <see cref="System.Data.Common.DbTransaction"/> 的实例。</param>
		/// <returns>返回 <see cref="QueryBuilder&lt;T&gt;"/> 的实例。</returns>
		public QueryBuilder<T> WithTransaction(DbTransaction transaction)
		{
			this.Query.WithTransaction(transaction);

			return this;
		}

		/// <summary>
		/// 提取查询结果到指定类型的对象。
		/// </summary>
		/// <typeparam name="TO">指定对象类型。</typeparam>
		/// <returns>返回指定类型的对象的实例。</returns>
		public TO Fetch<TO>() { return this.Query.Fetch<TO>(); }

		/// <summary>
		/// 提取查询结果到指定类型的集合。
		/// </summary>
		/// <typeparam name="TO">指定对象类型。</typeparam>
		/// <returns>返回指定类型的对象的集合。</returns>
		public List<TO> FetchAll<TO>() { return this.Query.FetchAll<TO>(); }

		/// <summary>
		/// 对连接对象执行 SQL 语句。
		/// </summary>
		public void Execute() { this.Query.Execute(); }

		/// <summary>
		/// 执行查询，并返回查询所返回的结果集中第一行的第一列。所有其他的列和行将被忽略。
		/// </summary>
		/// <typeparam name="TO">指定对象类型。</typeparam>
		/// <returns>返回指定类型的对象的实例。</returns>
		public TO ExecuteScalar<TO>() { return this.Query.ExecuteScalar<TO>(); }

		/// <summary>
		/// 提取 <see cref="MultiResult"/> 的实例。
		/// </summary>
		/// <returns>返回 <see cref="MultiResult"/> 的实例。</returns>
		public MultiResult FetchMultiple() { return this.Query.FetchMultiple(); }

		/// <summary>
		/// 提取 <see cref="System.Data.Common.DbDataReader"/> 的实例。
		/// </summary>
		/// <returns>返回 <see cref="System.Data.Common.DbDataReader"/> 的实例。</returns>
		public DbDataReader FetchReader() { return this.Query.FetchReader(); }

		/// <summary>
		/// 提取 <see cref="System.Data.DataSet"/> 的实例。
		/// </summary>
		/// <returns>返回 <see cref="System.Data.DataSet"/> 的实例。</returns>
		public DataSet FetchDataSet() { return this.Query.FetchDataSet(); }
	}
}
